﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using Estimate.Common.DBFieldTypes;
using Estimate.Common.Repository;
using Estimate.Common.Entity;

namespace Estimate.Common.DataImporter
{
    /// <summary>
    /// 将周学东处理的人工站实况文件读入数据库
    /// </summary>
    public class ManualStationImporter : IDataImporter
    {
        protected RainRealRepository rainRepository;

        protected TempRealRepository tempRepository;

        private Dictionary<string, List<string>> _TempProcessedData;

        private Dictionary<string, List<string>> _RainProcessedData;

        private RealDataLogRepository logRepository;

        /// <summary>
        /// 因为统计入库情况的需要，按天保存一个记录值
        /// </summary>
        private Dictionary<string,ImportDataQuality> _dateQuality;

        private string[] _stations;

        public ManualStationImporter(RainRealRepository rain, TempRealRepository temp, RealDataLogRepository log, string[] stations )
        {
            rainRepository = rain;
            tempRepository = temp;
            logRepository = log;
            _TempProcessedData = new Dictionary<string, List<string>>();
            _RainProcessedData = new Dictionary<string, List<string>>();
            _dateQuality = new Dictionary<string, ImportDataQuality>();
            _stations = stations;
        }

        private void addTempData(string dtStr, RealTempValueType type, string value)
        {
            string key = dtStr + "-" + type;
            if (!_TempProcessedData.ContainsKey(key))
                _TempProcessedData[key] = new List<string>();
            _TempProcessedData[key].Add(value);
        }

        private void addRainData(string dtStr, RealRainValueType type, string value)
        {
            string key = dtStr + "-" + type;
            if (!_RainProcessedData.ContainsKey(key))
                _RainProcessedData[key] = new List<string>();
            _RainProcessedData[key].Add(value);
        }

        public void Clear()
        {
            _dateQuality.Clear();
            _TempProcessedData.Clear();
            _RainProcessedData.Clear();
        }

        private void saveDataToDataBase()
        {
            RainRealEntity rainEntity = new RainRealEntity(DateTime.Now,RealRainValueType.D22);
            TempRealEntity tempEntity = new TempRealEntity(DateTime.Now, RealTempValueType.D8);

            foreach (KeyValuePair<string, List<string>> pair in _RainProcessedData)
            {
                string[] keys = pair.Key.Split('-');
                DateTime dt = new DateTime(Convert.ToInt32(keys[0].Substring(0, 4)), Convert.ToInt32(keys[0].Substring(4, 2)), Convert.ToInt32(keys[0].Substring(6, 2)));
                RealRainValueType type = (RealRainValueType)Enum.Parse(typeof(RealRainValueType), keys[1]);
                rainEntity.Date = dt;
                rainEntity.Type = type;
                rainEntity.Value = string.Join("|", pair.Value.ToArray());
                rainRepository.SetValue(rainEntity);
                AfterDataBeSaved(rainEntity);
            }

            foreach (KeyValuePair<string, List<string>> pair in _TempProcessedData)
            {
                string[] keys = pair.Key.Split('-');
                DateTime dt = new DateTime(Convert.ToInt32(keys[0].Substring(0, 4)), Convert.ToInt32(keys[0].Substring(4, 2)), Convert.ToInt32(keys[0].Substring(6, 2)));
                RealTempValueType type = (RealTempValueType)Enum.Parse(typeof(RealTempValueType), keys[1]);
                tempEntity.Date = dt;
                tempEntity.Type = type;
                tempEntity.Value = string.Join("|", pair.Value.ToArray());
                tempRepository.SetValue(tempEntity);
                AfterDataBeSaved(tempEntity);
            }              
        }
        public void ImportDataFromFile(string filepath)
        {
              

            Clear();            

            StreamReader file = new StreamReader(filepath);
            string line;
            string pattern = @"\ ";
            string dtStr;
            string stnum;
            float value;
            while (!file.EndOfStream)
            {
                line = file.ReadLine();                
                string[] lineserial = Regex.Split(line, pattern, RegexOptions.IgnoreCase);
                dtStr = lineserial[1];
                stnum = lineserial[0];

                /* 从 2011/07月起，人工站实况中，58151都转成了58154, 58248都转成了58252 */
                if (stnum == "58248")
                    stnum = "58252";
                if (stnum == "58151")
                    stnum = "58154";

                if (!_dateQuality.ContainsKey(dtStr))
                    _dateQuality[dtStr] = new ImportDataQuality(_stations);

                if (_dateQuality[dtStr].ExistStation(stnum))
                {
                    _dateQuality[dtStr].ProvideStation(stnum);
                    switch (lineserial[2].ToString())
                    {
                        case "08":

                            addRainData(dtStr, RealRainValueType.D88, lineserial[0] + ";" + lineserial[3]);

                            addTempData(dtStr, RealTempValueType.D8, lineserial[0] + ";" + lineserial[4]);

                            value = Convert.ToSingle(lineserial[4]);
                            if (value < -10f || value > 45f)
                            {
                                _dateQuality[dtStr].AddError(string.Format("{0}_{1}_{2}_{3}", stnum, RealTempValueType.D8.ToString(), "ErrorValue", lineserial[4]));
                            }

                            addTempData(dtStr, RealTempValueType.D18, lineserial[0] + ";" + lineserial[5]);
                            value = Convert.ToSingle(lineserial[5]);
                            if (value < -10f || value > 45f)
                            {
                                _dateQuality[dtStr].AddError(string.Format("{0}_{1}_{2}_{3}", stnum, RealTempValueType.D18.ToString(), "ErrorValue", lineserial[5]));
                            }

                            break;
                        case "20":
                            addRainData(dtStr, RealRainValueType.D22, lineserial[0] + ";" + lineserial[3]);

                            addTempData(dtStr, RealTempValueType.D2, lineserial[0] + ";" + lineserial[4]);
                            value = Convert.ToSingle(lineserial[4]);
                            if (value < -10f || value > 45f)
                            {
                                _dateQuality[dtStr].AddError(string.Format("{0}_{1}_{2}_{3}", stnum, RealTempValueType.D2.ToString(), "ErrorValue", lineserial[4]));
                            }

                            addTempData(dtStr, RealTempValueType.D12, lineserial[0] + ";" + lineserial[5]);
                            value = Convert.ToSingle(lineserial[5]);
                            if (value < -10f || value > 45f)
                            {
                                _dateQuality[dtStr].AddError(string.Format("{0}_{1}_{2}_{3}", stnum, RealTempValueType.D12.ToString(), "ErrorValue", lineserial[5]));
                            }
                            break;
                        default:
                            _dateQuality[dtStr].AddError(string.Format("{0}_{1}_{2}", stnum, lineserial[2].ToString(), "ErrorFactor"));
                            break;
                    }
                }
            }

            saveDataToDataBase();

            
            RealDataLogEntity logEntity = new RealDataLogEntity(ForeSemiType.Manual, DateTime.Now , filepath);
            foreach (KeyValuePair<string, ImportDataQuality> pair in _dateQuality)
            {
                DateTime dt = new DateTime(Convert.ToInt32(pair.Key.Substring(0, 4)), Convert.ToInt32(pair.Key.Substring(4, 2)), Convert.ToInt32(pair.Key.Substring(6, 2)));
                logEntity.RealDate = dt;

                ImportDataQuality quality = pair.Value;

                if (logRepository.IsRealDataExist(ForeSemiType.Manual, dt))
                {
                    logEntity = logRepository.GetRealDataWithDate(ForeSemiType.Manual, dt);
                    logEntity.ReimportCount += 1;
                    logEntity.FilePath = filepath;
                    logEntity.LastImportTime = DateTime.Now;
                }

                logEntity.Error = quality.ErrorCount;
                logEntity.ErrorString = quality.ErrorString;
                logEntity.Lack = quality.LackCount;
                logEntity.LackString = quality.LackString;
                logRepository.SetRecord(logEntity);
            }
        }

        /// <summary>
        /// 强制指定日期无效。该文件格式不支持
        /// 简单调用 ImportDataFromFile
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="dt"></param>
        public void ImportDataFromFileWithDate(string filepath, DateTime dt)
        {
            ImportDataFromFile(filepath);
        }

        public event EventHandler AfterDataInDatabase;

        public void AfterDataBeSaved(RainRealEntity entity)
        {
            object data = entity.Clone();
            if (AfterDataInDatabase != null)
            {
                AfterDataInDatabase(this, new FindDataEventArgs(data));
            }
        }

        public void AfterDataBeSaved(TempRealEntity entity)
        {
            object data = entity.Clone();
            if (AfterDataInDatabase != null)
            {
                AfterDataInDatabase(this, new FindDataEventArgs(data));
            }
        }

        /// <summary>
        /// 未实现该事件。目前用不到
        /// </summary>
        public event EventHandler BeforeDataInDatabase;

    }

           
    

}